﻿using System;
using System.Collections.Generic;
using System.Text;

namespace CRL.Transaction
{
    public enum TransStatus
    {
        Pending,
        Tried,
        TryError,
        Commited,
        Canceled,
        CommitError,
        CancelError
    }
    public interface IStep
    {
        string Name { get; }
        TransOptions TransOptions { get; set; }
        TransStatus Status { get; set; }
        //object GetArgs();
        object Args { get; set; }
        void SetArgs(object args);
        Type GetArgsType();
        void Commit();
        void Cancel();
        int Step { get; set; }
    }
    public abstract class AbsSagaStepBase : IStep
    {
        public TransOptions TransOptions { get; set; }
        public abstract string Name { get; }
        public int Step { get; set; }
        public TransStatus Status { get; set; }
        public void SetArgs(object args)
        {
            Args = args;
        }
        public abstract Type GetArgsType();
        public object Args { get; set; }

        ////以判断方法有没重载
        internal bool defaultCommit = false;
        internal bool defaultCancel = false;
        public virtual void Commit()
        {
            defaultCommit = true;
        }
        public virtual void Cancel()
        {
            defaultCancel = true;
        }
    }
    public abstract class AbsSagaStep<TArgs> : AbsSagaStepBase
    {
        public T GetMainArgs<T>()
        {
            return (T)TransOptions.Args;
        }
        public TArgs GetArgs() => (TArgs)Args;
        public override Type GetArgsType()
        {
            return typeof(TArgs);
        }
    }
    public abstract class AbsSagaStep : AbsSagaStep<string>
    {

    }
    class CustomSagaStep : AbsSagaStep<object>
    {
        internal Action commit;
        internal Action cancel;
        public override string Name => "CustomSagaStep";
        public CustomSagaStep(Action _commit, Action _cancel)
        {
            commit = _commit;
            cancel = _cancel;
        }
        public override void Cancel()
        {
            cancel?.Invoke();
        }

        public override void Commit()
        {
            commit?.Invoke();
        }
    }
}
